Skip to content

[testcore] Shared cluster pool for clusters that require WorkerService#10905

Open
long-nt-tran wants to merge 5 commits into
temporalio:mainfrom
long-nt-tran:system-worker-pool
Open

[testcore] Shared cluster pool for clusters that require WorkerService#10905
long-nt-tran wants to merge 5 commits into
temporalio:mainfrom
long-nt-tran:system-worker-pool

Conversation

@long-nt-tran

Copy link
Copy Markdown
Contributor

What changed?

Added a sharedWithWorker, which is a reusable pool of test clusters for cluster setups that require the system workers.

Why?

Right now, when a test requires system workers, we give it a dedicated cluster. However, this is heavy, and if we do this for all tests that require system workers, we risk a lot of OOM kills.

Technically speaking, reusing a cluster that has system workers is completely fine, so this PR does this by default (i.e., if we only enable system workers with no special configs, then we should aim to reuse this cluster).

For now, I'm creating a new shared pool of cluster-with-worker-service, rather than having a single shared pool, so we don't have to scan the entire pool to see which cluster is reusable.

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

Potential risks

Also re-enabled system workers + parallelization on some existing tests that were made to be sequential to avoid OOMs, so I'll watch out for OOMs from those.

@long-nt-tran
long-nt-tran requested review from a team as code owners July 1, 2026 22:36
@long-nt-tran
long-nt-tran marked this pull request as draft July 1, 2026 22:36
@long-nt-tran
long-nt-tran force-pushed the system-worker-pool branch 6 times, most recently from 64ac31e to db86e1e Compare July 2, 2026 21:41
Comment thread tests/testcore/onebox.go Outdated
Comment thread tests/leakcheck/leak_test.go Outdated
@long-nt-tran
long-nt-tran requested a review from stephanos July 6, 2026 15:00
@long-nt-tran
long-nt-tran marked this pull request as ready for review July 6, 2026 15:00
Comment thread tests/testcore/test_env.go
Comment thread tests/leakcheck/leak_test.go Outdated
}

func TestPollerScalingFunctionalSuite(t *testing.T) {
testcore.UseSuiteScopedCluster(t) //nolint:staticcheck // SA1019: suite reuses one worker-service cluster to avoid per-test cluster churn.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we delete UseSuiteScopedCluster now actually?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need it until we split versioning_3 suite

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good call!

Comment thread tests/testcore/test_cluster_pool.go Outdated
applyPoolSizeOverride(&sharedSize, "TEMPORAL_TEST_SHARED_CLUSTERS")

// System workers require significantly more memory, so default to a smaller pool.
sharedWorkerSize := max(1, runtime.GOMAXPROCS(0)/4)

@stephanos stephanos Jul 6, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intuitively, I would have started using the same size as for regular clusters but I think this works, too. We can tweak it later. We'll need to update testing.md to include the new env var, though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds fine to me, let me keep it the same as other pool (to be more optimistic) and if we still OOM we can make it smaller

Comment thread tests/testcore/test_env.go Outdated
Comment thread tests/testcore/onebox.go Outdated
Comment thread tests/testcore/onebox.go Outdated
Comment thread tests/testcore/test_cluster_pool.go Outdated
Comment thread tests/testcore/test_cluster_pool.go Outdated

@dnr dnr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW: my opinion is that the worker service is an integral part of the server and should always be run as part of the server. Yes, it's true that many tests work fine without it, but using worker is not a bad smell or anything, it shouldn't require going out of your way or apologizing, or this complexity of multiple pools.

(At least until several years in the future when all internal workflows can be ported to chasm)

Comment on lines +156 to +158
// Doing a no-op global metric capture to satisfy the dedicated cluster guard, otherwise
// we'll trigger a cluster misuse fatal.
env.StartGlobalMetricCapture()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stephanos using the WithMTLS() option causes more leaks, i spent a few tokens:

WithMTLS() is the cause. When the cluster tears down with mTLS enabled, the TLS connection becomes invalid. The sharedNamespaceWorker heartbeat RPC fails with a TLS error instead of a clean connection reset. TLS errors trigger a different
  retry classification in the grpc middleware — the goroutine parks in waitRetryBackoff for a longer, more deterministic backoff window. By the time goleak samples the stacks, the goroutine is reliably mid-retry.

  Without mTLS, the connection closes more cleanly — the goroutine either finishes the heartbeat or quickly returns to the idle (*sharedNamespaceWorker).run select loop, which IS in the ignore list. That race was nearly always won before.

  waitRetryBackoff still needs to be in the ignore list regardless — it's a transient state of the already-documented "SDK worker goroutines not fully stopped" leak.

I didn't want to add more ignores, doing this for now. But can also see a case for adding MTLS + ignore options, and then work to address those in a future PR. LMK if that's preferable

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StartGlobalMetricCapture is good for now 👍 let's leave mTLS cleanup for after we cleaned up the current batch

@long-nt-tran

long-nt-tran commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

FWIW: my opinion is that the worker service is an integral part of the server and should always be run as part of the server. Yes, it's true that many tests work fine without it, but using worker is not a bad smell or anything, it shouldn't require going out of your way or apologizing, or this complexity of multiple pools.

(At least until several years in the future when all internal workflows can be ported to chasm)

@dnr I agree with you in principle, IMO for integration/e2e tests, the user generally shouldn't even need to care about what services are spun up or whether they require a dedicated, shared cluster, etc... (basically configs that user need to set when spinning up clusters should generally be related to their business logic)

The mitigation here is mainly to deal with current testrunners hitting OOMs from spinning up too many "full clusters", without forcing test suites to run sequentially on a single cluster. Once we fix leaks when clusters are torn down + improving ergonomic of spinning up a test cluster, I want to get to a state where users don't actually need to care about needing to explicitly specifying these "backend config" options.

cc @stephanos if you want to add more context

@long-nt-tran
long-nt-tran requested a review from stephanos July 8, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants